home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / whati~gz.zoo / whatis.c < prev    next >
C/C++ Source or Header  |  1992-09-13  |  6KB  |  341 lines

  1. #undef DEBUG
  2. #undef CHECK_MAGIC
  3.  
  4. /*
  5.  *    whatis - show description of word from man database
  6.  * 
  7.  *     whatis [-l] [-P path] [-s sect] name ...
  8.  *
  9.  *    bugs:
  10.  *        - need more error checking (of data in database)
  11.  *        - perhaps a "magic number" for the database? it is
  12.  *          written, but #ifdef CHECK_MAGIC.
  13.  *
  14.  *    todo:
  15.  *        - allow "-s n name name -s m name ..."
  16.  *        - allow continuation lines in database:
  17.  *
  18.  *            name\
  19.  *            %1\
  20.  *            %...
  21.  */
  22.  
  23. static char *rcsid_whatis_c = "$Id: whatis.c,v 2.0 1992/09/13 05:02:44 rosenkra Exp $";
  24. /*
  25.  * $Log: whatis.c,v $
  26.  * Revision 2.0  1992/09/13  05:02:44  rosenkra
  27.  * total rewrite. this if first rev of this file.
  28.  *
  29.  *
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <string.h>
  34. #include <stdlib.h>
  35. #include <ctype.h>
  36.  
  37.  
  38. #include "whatis.h"
  39.  
  40.  
  41. /*
  42.  *    we only need one record here. we read a record and check all the
  43.  *    command line args against it for a match
  44.  */
  45. struct rec    r;
  46.  
  47. char           *libpath = MANPATH;    /* path to database files (-P) */
  48. int        debugging = 0;        /* for -d */
  49.  
  50.  
  51. /*
  52.  *    fcn prototypes
  53.  */
  54. void        whatis (int, int, int, char **);
  55. void        usage (int);
  56. int        parse_record (char *, struct rec *);
  57. void        print_record (int, struct rec *);
  58. #ifdef CHECK_MAGIC
  59. int        check_magic (void);
  60. #endif
  61.  
  62.  
  63.  
  64.  
  65. /*------------------------------*/
  66. /*    main            */
  67. /*------------------------------*/
  68. void main (int argc, char *argv[])
  69. {
  70.     int    sect = -1;
  71.     int    verbose = 0;
  72.     char   *lpath;
  73.     char   *ps;
  74.  
  75.  
  76.  
  77.     /*
  78.      *   see if there is MANPATH in env. use it over default...
  79.      */
  80.     if ((lpath = getenv ("MANPATH")) != (char *) NULL)
  81.         libpath = lpath;
  82.     else if ((lpath = getenv ("MANDIR")) != (char *) NULL)
  83.         libpath = lpath;
  84. #ifdef DEBUG
  85.     else
  86.         fprintf (stderr, "whatis: environment variable MANPATH not set, using default\n");
  87. #endif
  88.  
  89.  
  90.     /*
  91.      *   parse args
  92.      */
  93.     for (argc--, argv++; argc && **argv == '-'; argc--, argv++)
  94.     {
  95.         switch (*(*argv+1))
  96.         {
  97.         case 'P':            /* path for db */
  98.         case 'M':
  99.             argc--, argv++;
  100.             if (argc < 1)
  101.                 usage (1);
  102.             libpath = *argv;
  103.             break;
  104.  
  105.         case 's':            /* specific section */
  106.             argc--, argv++;
  107.             if (argc < 1)
  108.                 usage (1);
  109.             sect = **argv;
  110.             break;
  111.  
  112.         case 'l':            /* long (verbose) */
  113.             verbose = 1;
  114.             break;
  115.  
  116.         case 'd':            /* debug mode */
  117.             debugging = 1;
  118.             break;
  119.  
  120.         case 'h':            /* help */
  121.             usage (0);
  122.             /* NOTREACHED */
  123.         }
  124.     }
  125.  
  126.  
  127.  
  128.     /*
  129.      *   whatis what?
  130.      */
  131.     if (argc == 0)
  132.     {
  133.         fprintf (stderr,
  134.         "whatis: you must specify an argument. consider using whatisin.\n");
  135.         usage (1);
  136.     }
  137.  
  138.  
  139.  
  140.     /*
  141.      *   not documented: if first arg is a number, use it for section...
  142.      */
  143.     if (isdigit(**argv))
  144.     {
  145.         sect = **argv;
  146.         argc--, argv++;
  147.     }
  148.  
  149.  
  150.  
  151.     /*
  152.      *   do it. if specific section, search it only. else search all
  153.      *   sections
  154.      */
  155.     if (sect != -1)
  156.     {
  157.         whatis (verbose, sect, argc, argv);
  158.     }
  159.     else
  160.     {
  161.         for (ps = SECTIONS; *ps; ps++)
  162.         {
  163.             sect = *ps;
  164.             whatis (verbose, sect, argc, argv);
  165.         }
  166.     }
  167.  
  168.  
  169.     exit (0);
  170. }
  171.  
  172.  
  173.  
  174.  
  175. /*------------------------------*/
  176. /*    whatis            */
  177. /*------------------------------*/
  178. void whatis (int verbose, int sect, int argc, char **argv)
  179. {
  180.  
  181. #define MAX_ARGS    100
  182.  
  183.     char        dbname[256];
  184.     char        buf[REC_SIZE];
  185.     register char **vp;
  186.     int        notfound[MAX_ARGS];
  187.     int        i;
  188.  
  189.  
  190.  
  191.     /*
  192.      *   FIXME: we should allocate space for the notfound list.
  193.      */
  194.     if (argc > MAX_ARGS)
  195.         argc = MAX_ARGS;
  196.  
  197.  
  198.  
  199.     /*
  200.      *   set up db name. section is really a single ascii char, not an
  201.      *   int. this is so we can have whatis for local, new, etc.
  202.      */
  203.     if (sect == -1)
  204.         /* orig behavior (just single "whatis" file, never used here) */
  205.         sprintf (dbname, "%s%s%s", libpath, SLASH, WHATIS);
  206.     else
  207.         /* new: whatis._[0-9lno]_ */
  208.         sprintf (dbname, "%s%s%s._%c_", libpath, SLASH, WHATIS, sect);
  209.  
  210.  
  211.  
  212.     /*
  213.      *   reopen stdin as this file...
  214.      */
  215.     if (debugging)
  216.         fprintf (stderr, "checking database file %s...\n", dbname);
  217.     if (freopen (dbname, "r", stdin) == (FILE *) NULL)
  218.     {
  219. /*        if (verbose || debugging)*/
  220.         if (debugging)
  221.             fprintf (stderr,
  222.                 "whatis: could not access file %s\n", dbname);
  223.  
  224.         return;
  225.     }
  226.  
  227.  
  228.  
  229. #ifdef CHECK_MAGIC
  230.     /*
  231.      *   check file's magic
  232.      */
  233.     if (check_magic ())
  234.     {
  235.         fprintf (stderr,
  236.             "whatis: magic number is wrong for file %s\n",
  237.             dbname);
  238.  
  239.         return;
  240.     }
  241. #endif
  242.  
  243.  
  244.  
  245.     /*
  246.      *   read file and compare. first assume we will not find anything
  247.      *   and flag list...
  248.      */
  249.     for (i = 0; i < MAX_ARGS; i++)
  250.         notfound[i] = 1;
  251.     while (1)
  252.     {
  253.         /*
  254.          *   get raw record from file
  255.          */
  256.         fgets (buf, REC_SIZE-1, stdin);
  257.         if (feof (stdin))
  258.             break;
  259.         if (debugging)
  260.             fprintf (stderr, "%s", buf);
  261.  
  262.  
  263.  
  264.         /*
  265.          *   skip comment or blank lines
  266.          */
  267.         if (buf[0] == '#' || buf[0] == '\0' || buf[0] == '\n')
  268.             continue;
  269.  
  270.  
  271.  
  272.         /*
  273.          *   parse the record and store in r
  274.          */
  275.         parse_record (buf, &r);
  276.  
  277.         if (debugging)
  278.         {
  279.         fprintf (stderr, "name:    %s\n", r.name ? r.name : "(NULL)");
  280.         fprintf (stderr, "section: %s\n", r.section ? r.section : "(NULL)");
  281.         fprintf (stderr, "subsect: %s\n", r.subsect ? r.subsect : "(NULL)");
  282.         fprintf (stderr, "desc:    %s\n", r.desc ? r.desc : "(NULL)");
  283.         }
  284.  
  285.  
  286.  
  287.         /*
  288.          *   compare record's name field to all args from orig
  289.          *   command line. if we find one, flag notfound list
  290.          */
  291.         for (i = 0, vp = argv; i < argc && *vp; vp++, i++)
  292.         {
  293.             if (!strncmp (r.name, *vp, strlen (*vp)))
  294.             {
  295.                 print_record (verbose, &r);
  296.                 notfound[i] = 0;
  297.             }
  298.         }
  299.     }
  300.  
  301.  
  302.  
  303.     /*
  304.      *   print a message if we didn't find anything for the cmdline arg
  305.      */
  306.     if (verbose)
  307.     {
  308.         for (i = 0; i < argc; i++)
  309.         {
  310.             if (notfound[i])
  311.             {
  312.                 printf ("nothing found in section %c for %s\n",
  313.                     sect, argv[i]);
  314.             }
  315.         }
  316.     }
  317.  
  318.     return;
  319. }
  320.  
  321.  
  322.  
  323.  
  324. /*------------------------------*/
  325. /*    usage            */
  326. /*------------------------------*/
  327. void usage (int excode)
  328. {
  329. #define U(x)    fprintf(stderr,x);
  330.  
  331. U("usage: whatis [-l] [-P path] [-s section] name ...\n");
  332. U("       -l          long list\n");
  333. U("       -P path     alternative path to databases (MANPATH)\n");
  334. U("       -s section  search single section, not all\n");
  335. U("       name        valid name of a command, etc. if name is unknown,\n");
  336. U("                   consider using whatisin(1) or apropos(1).\n");
  337.  
  338. exit (excode);
  339. }
  340.  
  341.